/*
 * @Author: WangLi
 * @Date: 2021-07-27 16:41:40
 * @LastEditors: WangLi
 * @LastEditTime: 2021-08-03 23:12:29
 * @Description:
 */

import { requestAnimationFrame } from "../../../utils/util";

const getClassNames = (name) => ({
  enter: `s-${name}-enter s-${name}-enter-active`,
  "enter-to": `s-${name}-enter-to s-${name}-enter-active`,
  leave: `s-${name}-leave s-${name}-leave-active`,
  "leave-to": `s-${name}-leave-to s-${name}-leave-active`,
});

Component({
  options: {
    multipleSlots: true,
    addGlobalClass: true,
  },
  externalClasses: ["custom-class"],
  properties: {
    round: Boolean,
    closeable: Boolean,
    customStyle: String,
    overlayStyle: String,
    show: {
      type: Boolean,
      value: false,
      observer: "observeShow",
    },
    duration: {
      type: Number,
      value: 300,
    },
    transition: {
      type: String,
      observer: "observeClass",
    },
    overlayZIndex: {
      type: Number,
      value: 99,
    },
    zIndex: {
      type: Number,
      value: 100,
    },
    overlay: {
      type: Boolean,
      value: true,
    },
    position: {
      type: String,
      value: "center",
      observer: "observeClass",
    },
    closeOnClickOverlay: {
      type: Boolean,
      value: true,
    },
    safeAreaInsetBottom: {
      type: Boolean,
      value: true,
    },
    safeAreaInsetTop: {
      type: Boolean,
      value: false,
    },
  },
  data: {
    name: "",
    inited: false,
    display: false,
  },
  created() {
    this.observeClass();
  },
  methods: {
    observeShow(value, old) {
      if (value === old) {
        return;
      }
      value ? this.enter() : this.leave();
    },
    enter() {
      const { duration, name } = this.data;
      const classNames = getClassNames(name);
      const overlayClassNames = getClassNames("fade");
      this.status = "enter";
      requestAnimationFrame(() => {
        if (this.status !== "enter") {
          return;
        }
        this.setData({
          inited: true,
          display: true,
          classes: classNames.enter,
          overlayClasses: overlayClassNames.enter,
        });

        requestAnimationFrame(() => {
          if (this.status !== "enter") {
            return;
          }

          this.transitionEnded = false;
          this.setData({
            classes: classNames["enter-to"],
            overlayClasses: overlayClassNames["enter-to"],
          });
        });
      });
    },
    leave() {
      if (!this.data.display) {
        return;
      }
      const { duration, name } = this.data;
      const classNames = getClassNames(name);
      const overlayClassNames = getClassNames("fade");

      this.status = "leave";
      requestAnimationFrame(() => {
        if (this.status !== "leave") {
          return;
        }
        this.setData({
          classes: classNames.leave,
          overlayClasses: overlayClassNames.leave,
        });
        requestAnimationFrame(() => {
          if (this.status !== "leave") {
            return;
          }

          this.transitionEnded = false;
          setTimeout(() => this.onTransitionEnd(), duration);

          this.setData({
            classes: classNames["leave-to"],
            overlayClasses: overlayClassNames["leave-to"],
          });
        });
      });
    },
    onTransitionEnd() {
      if (this.transitionEnded) {
        return;
      }

      this.transitionEnded = true;

      const { show, display } = this.data;
      if (!show && display) {
        this.setData({ display: false });
      }
    },
    onClickOverlay() {
      this.triggerEvent("click-overlay");

      if (this.data.closeOnClickOverlay) {
        this.triggerEvent("close");
      }
    },
    observeClass() {
      // const { position } = this.data
      // this.setData({
      //   name: position,
      // })
      const { transition, position, duration } = this.data;
      const updateData = {
        name: transition || position,
      };
      if (transition === "none") {
        updateData.duration = 0;
        this.originDuration = duration;
      } else if (this.originDuration != null) {
        updateData.duration = this.originDuration;
      }
      this.setData(updateData);
    },
    noop() {},
  },
});
